# -*- coding: utf-8 -*-
"""
日志分析类
整合LLM调用、结果解析和存储功能
"""

import time
import json
from typing import List, Dict, Any, Optional
import pymysql
from pymysql.cursors import DictCursor
from common.logger import get_logger
from common.config import config
from common.utils import safe_json_dumps, chunk_list
from .llm_client import LLMClient
from .result_parser import ResultParser

logger = get_logger(__name__)


class LogAnalyzer:
    """日志分析器"""
    
    def __init__(self):
        """初始化日志分析器"""
        self.llm_client = LLMClient()
        self.result_parser = ResultParser()
        self.mysql_client = self._create_mysql_client()
        self.batch_size = 100
    
    def _create_mysql_client(self) -> pymysql.Connection:
        """
        创建MySQL客户端连接
        
        Returns:
            MySQL连接对象
        """
        mysql_config = config.get('mysql', {})
        
        try:
            connection = pymysql.connect(
                host=mysql_config.get('host', 'localhost'),
                port=mysql_config.get('port', 3306),
                user=mysql_config.get('user', 'root'),
                password=mysql_config.get('password', 'password'),
                database=mysql_config.get('database', 'log_analysis'),
                charset=mysql_config.get('charset', 'utf8mb4'),
                cursorclass=DictCursor,
                autocommit=True
            )
            
            logger.info(f"成功连接到MySQL: {mysql_config.get('host')}:{mysql_config.get('port')}")
            return connection
            
        except Exception as e:
            logger.error(f"连接MySQL失败: {e}")
            raise
    
    def analyze_log(self, log_data: Dict[str, Any], prompt_template: str = None) -> Optional[Dict[str, Any]]:
        """
        分析单条日志
        
        Args:
            log_data: 日志数据
            prompt_template: 提示词模板
            
        Returns:
            分析结果
        """
        try:
            log_message = log_data.get('message', '')
            if not log_message:
                logger.warning("日志消息为空，跳过分析")
                return None
            
            # 调用LLM分析
            analysis_result = self.llm_client.analyze_log(log_message, prompt_template)
            if not analysis_result:
                logger.warning("LLM分析失败")
                return None
            
            # 解析分析结果
            parsed_result = self.result_parser.parse_analysis_result(analysis_result)
            
            # 构建完整结果
            result = {
                'log_id': log_data.get('log_id'),
                'original_message': log_message,
                'analysis_result': analysis_result,
                'parsed_data': parsed_result,
                'analysis_timestamp': time.time(),
                'model_used': self.llm_client.model,
                'app_name': log_data.get('app_name'),
                'level': log_data.get('level'),
                'host': log_data.get('host')
            }
            
            return result
            
        except Exception as e:
            logger.error(f"分析日志失败: {e}")
            return None
    
    def analyze_logs(self, logs: List[Dict[str, Any]], prompt_template: str = None) -> List[Dict[str, Any]]:
        """
        批量分析日志
        
        Args:
            logs: 日志列表
            prompt_template: 提示词模板
            
        Returns:
            分析结果列表
        """
        results = []
        
        for log in logs:
            try:
                result = self.analyze_log(log, prompt_template)
                if result:
                    results.append(result)
                
                # 添加延迟避免请求过快
                time.sleep(0.1)
                
            except Exception as e:
                logger.error(f"分析单条日志失败: {e}")
                results.append({
                    'log_id': log.get('log_id'),
                    'original_message': log.get('message', ''),
                    'analysis_result': None,
                    'error': str(e),
                    'analysis_timestamp': time.time()
                })
        
        return results
    
    def store_analysis_result(self, result: Dict[str, Any]) -> bool:
        """
        存储单条分析结果到MySQL
        
        Args:
            result: 分析结果
            
        Returns:
            是否成功存储
        """
        try:
            with self.mysql_client.cursor() as cursor:
                sql = """
                INSERT INTO analysis_results (
                    log_id, app_name, level, host, original_message, 
                    analysis_result, parsed_data, model_used, 
                    analysis_timestamp, created_at
                ) VALUES (
                    %s, %s, %s, %s, %s, %s, %s, %s, %s, NOW()
                )
                """
                
                # 准备数据
                analysis_result = result.get('analysis_result', '')
                parsed_data = result.get('parsed_data', {})
                parsed_data_json = safe_json_dumps(parsed_data) if parsed_data else None
                
                values = (
                    result.get('log_id'),
                    result.get('app_name'),
                    result.get('level'),
                    result.get('host'),
                    result.get('original_message'),
                    analysis_result,
                    parsed_data_json,
                    result.get('model_used'),
                    result.get('analysis_timestamp')
                )
                
                cursor.execute(sql, values)
                return True
                
        except Exception as e:
            logger.error(f"存储分析结果失败: {e}")
            return False
    
    def store_analysis_results(self, results: List[Dict[str, Any]]) -> int:
        """
        批量存储分析结果到MySQL
        
        Args:
            results: 分析结果列表
            
        Returns:
            成功存储的结果数量
        """
        if not results:
            return 0
        
        try:
            with self.mysql_client.cursor() as cursor:
                sql = """
                INSERT INTO analysis_results (
                    log_id, app_name, level, host, original_message, 
                    analysis_result, parsed_data, model_used, 
                    analysis_timestamp, created_at
                ) VALUES (
                    %s, %s, %s, %s, %s, %s, %s, %s, %s, NOW()
                )
                """
                
                values_list = []
                for result in results:
                    # 准备数据
                    analysis_result = result.get('analysis_result', '')
                    parsed_data = result.get('parsed_data', {})
                    parsed_data_json = safe_json_dumps(parsed_data) if parsed_data else None
                    
                    values = (
                        result.get('log_id'),
                        result.get('app_name'),
                        result.get('level'),
                        result.get('host'),
                        result.get('original_message'),
                        analysis_result,
                        parsed_data_json,
                        result.get('model_used'),
                        result.get('analysis_timestamp')
                    )
                    values_list.append(values)
                
                # 批量插入
                cursor.executemany(sql, values_list)
                stored_count = len(results)
                logger.info(f"成功存储 {stored_count} 条分析结果到MySQL")
                return stored_count
                
        except Exception as e:
            logger.error(f"批量存储分析结果失败: {e}")
            return 0
    
    def analyze_and_store_logs(self, logs: List[Dict[str, Any]], prompt_template: str = None) -> Dict[str, Any]:
        """
        分析并存储日志
        
        Args:
            logs: 日志列表
            prompt_template: 提示词模板
            
        Returns:
            处理结果统计
        """
        start_time = time.time()
        
        # 分析日志
        analysis_results = self.analyze_logs(logs, prompt_template)
        
        # 分批存储
        total_stored = 0
        chunks = chunk_list(analysis_results, self.batch_size)
        
        for chunk in chunks:
            stored_count = self.store_analysis_results(chunk)
            total_stored += stored_count
        
        end_time = time.time()
        processing_time = end_time - start_time
        
        stats = {
            'original_count': len(logs),
            'analyzed_count': len(analysis_results),
            'stored_count': total_stored,
            'failed_count': len(logs) - len(analysis_results),
            'processing_time_seconds': processing_time,
            'processing_rate': len(logs) / processing_time if processing_time > 0 else 0
        }
        
        logger.info(f"分析完成: {stats}")
        return stats
    
    def get_analysis_stats(self) -> Dict[str, Any]:
        """
        获取分析统计信息
        
        Returns:
            分析统计信息
        """
        try:
            with self.mysql_client.cursor() as cursor:
                # 获取总记录数
                cursor.execute("SELECT COUNT(*) as total FROM analysis_results")
                total_count = cursor.fetchone()['total']
                
                # 获取各级别统计
                cursor.execute("""
                    SELECT level, COUNT(*) as count 
                    FROM analysis_results 
                    GROUP BY level
                """)
                level_stats = {row['level']: row['count'] for row in cursor.fetchall()}
                
                # 获取各应用统计
                cursor.execute("""
                    SELECT app_name, COUNT(*) as count 
                    FROM analysis_results 
                    WHERE app_name IS NOT NULL
                    GROUP BY app_name
                """)
                app_stats = {row['app_name']: row['count'] for row in cursor.fetchall()}
                
                # 获取模型使用统计
                cursor.execute("""
                    SELECT model_used, COUNT(*) as count 
                    FROM analysis_results 
                    WHERE model_used IS NOT NULL
                    GROUP BY model_used
                """)
                model_stats = {row['model_used']: row['count'] for row in cursor.fetchall()}
                
                return {
                    'total_analysis_results': total_count,
                    'level_statistics': level_stats,
                    'app_statistics': app_stats,
                    'model_statistics': model_stats,
                    'llm_stats': self.llm_client.get_usage_stats(),
                    'parser_stats': self.result_parser.get_parsing_stats()
                }
                
        except Exception as e:
            logger.error(f"获取分析统计信息失败: {e}")
            return {}
    
    def get_recent_analysis_results(self, limit: int = 100) -> List[Dict[str, Any]]:
        """
        获取最近的分析结果
        
        Args:
            limit: 返回结果数量限制
            
        Returns:
            分析结果列表
        """
        try:
            with self.mysql_client.cursor() as cursor:
                sql = """
                SELECT * FROM analysis_results 
                ORDER BY created_at DESC 
                LIMIT %s
                """
                cursor.execute(sql, (limit,))
                return cursor.fetchall()
                
        except Exception as e:
            logger.error(f"获取最近分析结果失败: {e}")
            return []
    
    def get_analysis_results_by_app(self, app_name: str, limit: int = 100) -> List[Dict[str, Any]]:
        """
        根据应用名称获取分析结果
        
        Args:
            app_name: 应用名称
            limit: 返回结果数量限制
            
        Returns:
            分析结果列表
        """
        try:
            with self.mysql_client.cursor() as cursor:
                sql = """
                SELECT * FROM analysis_results 
                WHERE app_name = %s
                ORDER BY created_at DESC 
                LIMIT %s
                """
                cursor.execute(sql, (app_name, limit))
                return cursor.fetchall()
                
        except Exception as e:
            logger.error(f"获取应用分析结果失败: {e}")
            return []
    
    def get_analysis_results_by_level(self, level: str, limit: int = 100) -> List[Dict[str, Any]]:
        """
        根据日志级别获取分析结果
        
        Args:
            level: 日志级别
            limit: 返回结果数量限制
            
        Returns:
            分析结果列表
        """
        try:
            with self.mysql_client.cursor() as cursor:
                sql = """
                SELECT * FROM analysis_results 
                WHERE level = %s
                ORDER BY created_at DESC 
                LIMIT %s
                """
                cursor.execute(sql, (level, limit))
                return cursor.fetchall()
                
        except Exception as e:
            logger.error(f"获取级别分析结果失败: {e}")
            return []
    
    def close(self):
        """关闭连接"""
        try:
            if self.mysql_client:
                self.mysql_client.close()
            logger.info("日志分析器连接已关闭")
        except Exception as e:
            logger.error(f"关闭连接时发生错误: {e}") 